import fs from 'fs';
import path from 'path';
import Database from 'better-sqlite3';

/**
 * 数据库备份和恢复工具
 */
export class BackupUtil {
  /**
   * 创建数据库备份
   * @param db 数据库实例
   * @param backupPath 备份文件路径
   * @param callback 可选的进度回调函数
   * @returns 成功返回true，失败返回false
   */
  public static backup(
    db: Database.Database, 
    backupPath: string, 
    callback?: (progress: { totalPages: number; remainingPages: number }) => void
  ): boolean {
    try {
      // 确保目标目录存在
      const backupDir = path.dirname(backupPath);
      if (!fs.existsSync(backupDir)) {
        fs.mkdirSync(backupDir, { recursive: true });
      }

      // 创建目标文件副本
      const backupDb = new Database(backupPath);
      
      // 执行数据库备份
      const backupToFile = () => {
        // 创建备份数据流
        const source = fs.createReadStream(db.name);
        const dest = fs.createWriteStream(backupPath);
        
        let totalBytes = 0;
        let processedBytes = 0;
        
        source.on('data', (chunk) => {
          processedBytes += chunk.length;
          if (callback) {
            callback({
              totalPages: totalBytes > 0 ? Math.ceil(totalBytes / 4096) : 0,
              remainingPages: totalBytes > 0 ? Math.ceil((totalBytes - processedBytes) / 4096) : 0
            });
          }
        });
        
        return new Promise<void>((resolve, reject) => {
          source.on('error', (err) => reject(err));
          dest.on('error', (err) => reject(err));
          dest.on('finish', () => resolve());
          source.pipe(dest);
        });
      };
      
      // 执行备份
      fs.copyFileSync(db.name, backupPath);
      backupDb.close();
      
      return true;
    } catch (error) {
      console.error('数据库备份失败:', error);
      return false;
    }
  }

  /**
   * 从备份文件恢复数据库
   * @param backupPath 备份文件路径
   * @param targetDbPath 目标数据库路径
   * @param callback 可选的进度回调函数
   * @returns 成功返回true，失败返回false
   */
  public static restore(
    backupPath: string, 
    targetDbPath: string, 
    callback?: (progress: { totalPages: number; remainingPages: number }) => void
  ): boolean {
    try {
      // 确保目标目录存在
      const targetDir = path.dirname(targetDbPath);
      if (!fs.existsSync(targetDir)) {
        fs.mkdirSync(targetDir, { recursive: true });
      }

      // 检查源文件是否存在
      if (!fs.existsSync(backupPath)) {
        throw new Error(`备份文件不存在: ${backupPath}`);
      }

      // 如果目标文件已存在则先删除
      if (fs.existsSync(targetDbPath)) {
        fs.unlinkSync(targetDbPath);
      }

      // 直接复制文件
      fs.copyFileSync(backupPath, targetDbPath);
      
      // 验证恢复的数据库
      try {
        const testDb = new Database(targetDbPath);
        testDb.close();
      } catch (err) {
        throw new Error(`恢复的数据库文件损坏或无效: ${err}`);
      }
      
      // 模拟进度回调
      if (callback) {
        callback({
          totalPages: 1,
          remainingPages: 0
        });
      }
      
      return true;
    } catch (error) {
      console.error('数据库恢复失败:', error);
      return false;
    }
  }
} 